/*******************************************************************************
 * Package: com.song.boot.springstudy.ms.szjz
 * Type:    PriceFetcherV2
 * Date:    2025/8/8 11:11
 *
 * Copyright (c) 2025 LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.song.boot.springstudy.ms.szjz.al5;

import lombok.SneakyThrows;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 功能描述：
 *
 * @author Songxianyang
 * @date 2025/8/8 11:11
 */
public class PriceFetcherV2 {
    public PriceFetcherV2() {
        runTask();
    }

    public static void main(String[] args) {
        // System.out.println(callThirdPartyAPI("ss"));

        // v2.invokeTheTask();

        for (int i = 0, size = 10; i < size; i++) {
            PriceFetcherV2 v2 = new PriceFetcherV2();
            int finalI = i;
            v2.submitRequest(()->{
                System.out.println(callThirdPartyAPI(String.valueOf(finalI)));
            });
        }
        // 等待所有请求处理完成后关闭
        new Thread(() -> {
            try {
                // 等待足够长的时间让所有请求处理完成
                Thread.sleep(10 * 1000);
                shutdown_01();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();

    }


    // 每秒处理5个请求，所以请求之间的间隔应为200毫秒
    private static final long MS_200 = 200;
    // 把任务放到队列当中
    private static LinkedBlockingQueue<Runnable> wordQueue = new LinkedBlockingQueue<>();
    // 创建单线程池来处理请求，保证顺序执行
    private static ExecutorService processor = Executors.newSingleThreadExecutor();

    // 提交任务,放队列
    @SneakyThrows
    private static void submitRequest(Runnable runnable) {
        wordQueue.put(runnable);
    }

    // 控制速率 执行任务

    private static void runTask() {
        processor.execute(()->{
            try {
                Runnable runnable = wordQueue.take();
                runnable.run();
                // MS_200
                TimeUnit.MILLISECONDS.sleep(MS_200);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    // 关闭线程池
    public static void shutdown_01() {
        processor.shutdown();
    }


    // 调用任务
    // invokeTheTask
    private static void invokeTheTask() {
        for (int i = 0, size = 10; i < size; i++) {
            int finalI = i;
            submitRequest(()->{
                System.out.println(callThirdPartyAPI(String.valueOf(finalI)));
            });
        }
        // 等待所有请求处理完成后关闭
        new Thread(() -> {
            try {
                // 等待足够长的时间让所有请求处理完成
                Thread.sleep(10 * 1000);
                shutdown_01();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }


    // 模拟第三方API调用
    @SneakyThrows
    private static Double callThirdPartyAPI(String time)  {
        // 每秒处理5个请求


        // 模拟网络延迟 (100ms ~ 1000ms)
        int delay = 100 + (int)(Math.random() * 900);
        Thread.sleep(delay);

        // 生成随机价格作为模拟结果
        return Double.parseDouble(String.format("%.2f", Math.random() * 100));
    }
}
